package com.bsi.exception;

import com.bsi.pojo.ResultJson;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;


/**
 * 扩展oauth对于token失效过期等异常处理
 */
public class Auth2ResponseExceptionTranslator implements WebResponseExceptionTranslator {

    protected final Logger logger = LoggerFactory.getLogger(Auth2ResponseExceptionTranslator.class);

    private static final String AUTH_HEADER_NAME = "Authorization";

    @Override
    public ResponseEntity<OAuth2Exception> translate(Exception e) throws Exception {
        logger.error("=======================网关异常，Auth2校验不通过异常start===============");
        logger.error("异常信息为:{}", e.getLocalizedMessage());
        ResultJson resultJson = new ResultJson();
        resultJson.setStatus("0");
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if (requestAttributes == null) {  // 说明访问路径不正确打回前端
            logger.error("异常原因:{}", "访问url格式不正确，请重试!");
            resultJson.setErrorMessage("访问url格式不正确，请重试!");
            resultJson.setCode(HttpStatus.NOT_FOUND.value());
            return new ResponseEntity(resultJson, HttpStatus.OK);
        }
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
        logger.error("访问路径为:{}", request.getRequestURI());
        if (e instanceof InsufficientAuthenticationException) {  // 未携带token直接访问
            if (!StringUtils.isEmpty(request.getHeader(AUTH_HEADER_NAME))) {
                resultJson.setErrorMessage("检验出token不是正确的格式，请重试！");
                logger.error("异常原因为:{}", "检验出token不是正确的格式，请重试");
            } else {
                resultJson.setErrorMessage("请登录后再进行操作！");
                logger.error("异常原因为:{}", "未携带token直接访问");
            }
            resultJson.setCode(HttpStatus.UNAUTHORIZED.value());
        }
        Throwable throwable = e.getCause();
        if (throwable instanceof InvalidTokenException) { // 携带token，但是token校验错误
            resultJson.setCode(HttpStatus.UNAUTHORIZED.value());
            resultJson.setErrorMessage("token校验失败,请重新登录");
            logger.error("异常原因为:{}", "token校验失败");
        }
        logger.error("=======================网关异常，Auth2校验不通过异常end===============");
        return new ResponseEntity(resultJson, HttpStatus.OK);
    }
}
